home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga CD-Sensation: Golden Games
/
Amiga CD-Sensation - Ausgabe 2 - Golden Games (1996)(GTI - Schatztruhe)(DE)[!].iso
/
Archive
/
Funny Stuff
/
PigLatin.lha
/
PigLatin
/
pig.c
next >
Wrap
C/C++ Source or Header
|
1986-04-08
|
16KB
|
396 lines
#include "exec/types.h" /*Filename: pig.c */
#include "lattice/stdio.h"
#include "lattice/ctype.h" /* Copyright March, 1986 by */
#include "libraries/translator.h" /* Thomas W. Clement. */
#include "devices/narrator.h" /* Licence is hereby given for */
#include "exec/exec.h" /* the non-commercial use and */
#include "exec/nodes.h" /* duplication of all or part of */
#include "exec/memory.h" /* this program, expressly */
#include "exec/interrupts.h" /* conditioned, however, upon the */
#include "exec/ports.h" /* inclusion of this copyright */
#include "exec/libraries.h" /* notice and licencing agreement */
#include "exec/io.h" /* in any copy made. */
#include "exec/execbase.h"
#define REVISION 1
struct MsgPort *writeport = 0; /* Write reply port. */
struct narrator_rb *writeNarrator = 0; /* Pointer to IORB. */
struct Library *TranslatorBase = 0; /* Ptr to Translator fn. */
extern struct MsgPort *CreatePort(); /* External functions */
extern struct Library *OpenLibrary(); /* are declared here. */
char obuff[1024]; /* Buffer sent to translate device.*/
char phonemeBuff[2048]; /* Buffer for translated string. */
char *pobuff; /* Pointer to obuff. */
int error; /* Error code. */
UWORD Rate = 100; /* Rate of speaking voice. (Slower */
/* than usual default value.) */
UWORD Pitch = DEFPITCH; /* Pitch of speaking voice. (110) */
UWORD Sex = DEFSEX; /* Sex of speaking voice. (Male) */
UWORD Mode = DEFMODE; /* Mode of voice. (Natural) */
UWORD Sampfreq = 25000; /* Sampling freq. (A bit higher.) */
char audChanMasks[4] = { 3, 5, 10, 12 }; /* Audio chan. allocation */
/* map. see ch 12 ROM K.M. */
/* This program accepts characters from stdin until a ".", "!", or "?" is
* seen, then prints the piglatin equivalent to standard output and
* uses the AMIGA's speaking abilities to say the piglatin equivalent.
*/
main()
{
/* Main() assembles characters into words which are passed on to
* pig() for conversion into pig latin. An imbedded apostrophe
* is considered a part of the word. When a sentence is assembled,
* it is passed on to sayit() for enunciation.
*/
char wbuff[64]; /* Single word buffer. */
char *pwbuff; /* Pointer to wbuff. */
int c; /* Current character. */
int nopig = 0; /* Flag for regular speech. */
void setup_speech(); /* Declare function. */
void cleanup(); /* Declare cleanup function. */
void set_voice(); /* Declare voice specifier. */
pobuff = obuff; /* Initialize pobuff. */
printf( "Do you want to set voice characteristics? ( y or n ): " );
gets( wbuff );
if( *wbuff == 'y' || *wbuff == 'Y' )
{
set_voice(); /* Routine to change voice. */
}
printf( "Piglatin or regular speech? ( 'p' or 'r' ) :" );
gets( wbuff );
if( *wbuff == 'r' || *wbuff == 'R' )
{
nopig = -1; /* Set flag for normal speech.*/
}
setup_speech(); /* Initialize speech stuff. */
printf( "Enter sentences ending with \".\", \"!\" or \"?\".\n" );
wbuff[0] = '\0'; /* Buffer starts at wbuff[1]. */
c = getchar(); /* Get first character. */
while( c != EOF ) /* Exit cleanly on EOF. */
{
if( Chk_Abort() ) /* Exit cleanly on ^C or ^D. */
{
printf( "** Break **\n" ); /* Announce break on ^C or ^D.*/
break; /* Gets to cleanup routines. */
}
pwbuff = wbuff + 1; /* Pointer to 1st wbuff char. */
if( !isalpha(c) ) /* Skip all non-alphabetics. */
{
*pobuff++ = c; /* Add the character to obuff.*/
if( c == '.' | c == '?' | c == '!' ) /* End of sentence? */
{
*pobuff = '\0'; /* Null terminate obuff. */
if( !nopig )
{
printf("%s\n", obuff); /* Print what's in the buffer.*/
}
sayit(); /* Call speech routine. */
pobuff = obuff; /* Reset output buffer ptr. */
}
c = getchar(); /* Update current character. */
}
else /* Collect & pass word to pig.*/
{
while( isalpha(c) || c == '\'' )
{
*pwbuff++ = c; /* Word - alphabetic chars & */
c = getchar(); /* imbedded apostrophes. */
}
*pwbuff = '\0'; /* Terminate word w/ null. */
if( nopig )
{
strcpy( pobuff, wbuff + 1 ); /* Copy word to */
pobuff += pwbuff - ( wbuff + 1 ); /* obuff w/o change.*/
}
else
{
pig( wbuff + 1 ); /* Sooeey. ( Call pig. ) */
}
}
}
cleanup(); /* Close devices,ports, libs. */
exit( 0 );
}
pig( word )
char *word;
{
/* Pig() takes a pointer to a word passed from main(), and assembles
* the pig latin equivalent.
*/
char *sword = word; /* Pointer to word. */
int length; /* Length of string. */
if( *( sword + 1 ) == '\0' ) /* Don't change single letter */
{ /* words. */
*pobuff++ = *sword; /* Add to output buff. */
if( *sword == 'a' || *sword == 'A' ) /* Add more if word was */
{ /* "A" or "a"-- make it */
(void)strcpy( pobuff, "n-yay" ); /* "an-yay". (The next */
pobuff += 5; /* word will start with */
} /* a vowel.) */
}
else if( isvowel( sword ) ) /* If it begins with a vowel */
{ /* pigword is word with "yay" */
length = strlen( word ); /* added to the end. */
(void)strcpy( pobuff, word ); /* Copy word to obuff. */
pobuff += length; /* Advance pobuff. */
(void)strcpy( pobuff, "-yay" ); /* Copy "-yay" to obuff. */
pobuff += 4; /* Advance pobuff. */
}
else /* Consonant starts a word. */
{
while( !isvowel( sword ) && *sword != '\0' ) /* Find 1st vowel */
{ /* or word end. */
++sword;
}
if( *sword == '\0' ) /* If there are no vowels in */
{ /* the word, don't change it. */
length = strlen( word );
(void)strcpy( pobuff, word ); /* Copy the word to obuff. */
pobuff += length; /* Advance pobuff. */
}
else
{
if( isupper( *word ) ) /* If upper case, */
{
*word += 32; /* change to lower case, and */
*sword = toupper( *sword ); /* change new 1st lett to UC. */
}
length = strlen( sword ); /* Get length of substring. */
(void)strcpy( pobuff, sword ); /* Copy it to obuff. */
pobuff += length; /* Advance pobuff. */
*pobuff++ = '-'; /* Add a hyphen for clarity. */
*sword = '\0'; /* Terminate consonant part. */
length = strlen( word ); /* Get length of cons part. */
(void)strcpy( pobuff, word ); /* Copy cons part to obuff. */
pobuff += length; /* Advance pobuff. */
(void)strcpy( pobuff, "ay" ); /* Add "ay" to the string. */
pobuff += 2; /* Advance pobuff. */
}
}
}
isvowel( p )
char *p;
{
/* This routine returns true if the character is a vowel.
* For the purposes of this program, 'u' is not considered a
* vowel if it follows a 'q'. 'Y' is considered a vowel if it
* is followed by a consonant. Notice that 'y' will be treated
* as a vowel in the program only where either:
* 1. It starts a word and is followed by a consonant, or
* 2. It is preceeded by a string of only consonants and is
* followed by a consonant.
*/
char c; /* Current character, ( pointer to by p ). */
if( ( c = tolower( *p ) ) == 'a' || c == 'e' || c == 'i' || c == 'o'
|| ( c == 'u' && tolower( *( p-1 ) ) != 'q' )
|| ( c == 'y' && !isvowel( p + 1 ) ) )
{
return 1; /* Return true if a "vowel" as we define it. */
}
return 0; /* Otherwise return false. */
}
void setup_speech()
{
/* This function sets up the translator library and the speech device of
* the AMIGA. If it fails for some reason, it trys to let you know why.
*/
if((TranslatorBase = OpenLibrary("translator.library", REVISION)) == NULL)
{
printf( "Can't open Translator library.\n" );
error = 1;
cleanup();
}
if( ( writeport = CreatePort( 0, 0 ) ) == NULL )
{
printf( "CreatePort problems.\n" );
error = 2;
cleanup();
}
/* Note that memory is allocated directly, instead of using the
* function CreateExtIO(). This is because I couldn't find this
* function anywhere in my release. Anyway, this seems to work O.K.
* so I suppose I can't complain.
*/
if( ( writeNarrator = (struct narrator_rb *)AllocMem( sizeof(
struct narrator_rb), MEMF_PUBLIC | MEMF_CLEAR ) ) == NULL )
{
printf( "Can't allocate memory for writeNarrator IORB.\n" );
error = 3;
cleanup();
}
/* Specify the type of node in the linked list, the priority of the
* message, and the address of the prot created with CreatePort().
*/
writeNarrator->message.io_Message.mn_Node.ln_Type = NT_MESSAGE;
writeNarrator->message.io_Message.mn_Node.ln_Pri = 0;
writeNarrator->message.io_Message.mn_ReplyPort = writeport;
writeNarrator->ch_masks = audChanMasks; /* Audio channels. */
writeNarrator->nm_masks = sizeof( audChanMasks ); /* # of Audio chans. */
writeNarrator->message.io_Command = CMD_WRITE; /* Command for IO. */
if( OpenDevice( "narrator.device", 0, writeNarrator, 0 ) )
{
printf( "Can't open narrator device.\n" );
error = 4;
cleanup();
}
writeNarrator->rate = Rate; /* Set these values to the */
writeNarrator->pitch = Pitch; /* defaults, or the user */
writeNarrator->sex = Sex; /* specified values if the */
writeNarrator->mode = Mode; /* function set_voice was */
writeNarrator->sampfreq = Sampfreq; /* called. */
return;
}
void cleanup()
{
if( writeNarrator ) /* If the narrator device had been */
{ /* close it & free up memory. */
CloseDevice( writeNarrator );
FreeMem( writeNarrator, sizeof( struct narrator_rb ) );
}
if( writeport )
{ /* If the port had been */
DeletePort( writeport ); /* created, delete it. */
}
if( TranslatorBase ) /* If the translator */
{ /* library had been opened,*/
CloseLibrary( TranslatorBase ); /* close it. */
}
if( error ) /* Tell user what went wrong. */
{
fprintf( stderr, "Error #%d, execution terminated.\n", error );
exit( error );
}
}
sayit()
{
/* This function speaks the pig latin. It translates the string in
* obuff, placing the result in phonemeBuff. It then sets a couple
* of fields in the narrator IORB (Input Output Request Block), and
* sends the phonemes into the ether.
*/
if( Translate( obuff, pobuff-obuff, phonemeBuff, 2048 ) )
{
printf( "Translator output buffer overflow.\n" );
error = 5;
cleanup();
}
writeNarrator->message.io_Data = (APTR)phonemeBuff; /* Ph. source. */
writeNarrator->message.io_Length = strlen(phonemeBuff); /* Length. */
if( DoIO( writeNarrator ) )
{
printf( "Can't perform DoIO.\n" );
error = 6;
cleanup();
}
}
int atoi(s)
char *s; /* This is a simple version of atoi suitable for our use. */
{ /* ( atoi changes a string into an integer ). */
int n;
for( n = 0; *s >= '0' && *s <= '9'; s++ )
{
n = 10 * n + *s - '0';
}
return( n );
}
void set_voice()
{
char answer[10]; /* Char array for answers.*/
printf( "Male or female? ( m or f ): " );
gets( answer );
if( *answer == 'f' || *answer == 'F' )
{
Sex = FEMALE;
}
printf( "How many words per minute? (40 to 400): " );
gets( answer );
if( *answer != '\0' )
{
Rate = atoi( answer ); /* Convert answer to int. */
Rate = max( Rate, MINRATE ); /* Make Rate >= minimum. */
Rate = min( Rate, MAXRATE ); /* Make Rate <= maximum. */
}
printf( "What pitch speech? (65 to 320): " );
gets( answer );
if( *answer != '\0' )
{
Pitch = atoi( answer ); /* Convt answer to int. */
Pitch = max( Pitch, MINPITCH ); /* Make Pitch >= minimum. */
Pitch = min( Pitch, MAXPITCH ); /* Make Pitch <= maximum. */
}
printf( "What sampling frequency? ( 5000 to 28000 ): " );
gets( answer );
if( *answer != '\0' )
{
Sampfreq = atoi( answer ); /* Convt answer to int. */
Sampfreq = max( Sampfreq, MINFREQ ); /* Ensure that sampling */
Sampfreq = min( Sampfreq, MAXFREQ ); /* freq is w/in range. */
}
printf( "What mode of speech? (Natural or Monotone): " );
gets( answer );
if ( *answer == 'M' || *answer == 'm' )
{
Mode = ROBOTICF0; /* Monotone voice. */
}
return;
}